#include <iostream>
#include <vector>
#include <stdio.h>
#include <stdint.h>
#define MAX 10000000
using namespace std;

uint32_t ans;
uint32_t rstep = 0;


class Matrix {
	public:
		int row, col;
		int* pm;
	public:
		Matrix() { }
		Matrix(int r, int c) {
			row = r;
			col = c;
			pm = new int[r*c];
		}
		Matrix(const Matrix& m) {
			row = m.row;
			col = m.col;
			pm = new int[row*col];
			for (int i = 0; i < row; i++)
				for (int j = 0; j < col; j++)
					set(i, j, m.at(i, j));
		}
		int at(int r, int c) const {
			return pm[ r * col + c ];
		}
		void set(int r, int c, int v) {
			pm[ r * col + c ] = v;
		}
		void setCol(int c) {
			col = c;
		}
		void setRow(int r) {
			row = r;
		}
};

istream&  operator>>(istream& in, Matrix& m)
{
	for (int r = 0; r < m.row; r++) {
		for (int c = 0; c < m.col; c++) {
			int v;
			in >> v;
			m.set(r, c, v);
		}
	}
	return in;
}

ostream& operator<<(ostream& out, const Matrix& m)
{
	for (int r = 0; r < m.row; r++) {
		for (int c = 0; c < m.col; c++) 
			out << m.at(r, c) << "   ";
		out << endl;
	}
	out << endl;
	return out;
}
	
ostream& operator<<(ostream& out, vector<int>& vec)
{
	for (vector<int>::iterator iter = vec.begin(); iter < vec.end(); iter++) {
		out << *iter << " ";
	}
	out << endl;
	return out;
}

bool operator==(const Matrix& m1, const Matrix& m2) {
	if (m1.row != m2.row || m1.col != m2.col) return false;
	for (int i = 0; i < m1.row; i++)
		for (int j = 0; j < m1.col; j++) 
			if (m1.at(i, j) != m2.at(i, j))
				return false;
	return true;
}

int compareColumn(const Matrix& m1, const Matrix& m2, int col1, int col2) {
	for (int i = 0; i < m1.row; i++) 
		if (m1.at(i, col1) != m2.at(i, col2))
			return -1;
	return 0;
}

bool in(const int col, const vector<int>& vec) {
	for (vector<int>::const_iterator iter = vec.begin(); iter < vec.end(); iter++) 
		if (*iter == col)
			return true;
	return false;
}

Matrix& colChange(const Matrix& m, int col1, int col2)
{
	Matrix* mo = new Matrix(m);
	for (int i = 0; i < m.row; i++) {
		int temp = mo->at(i, col1);
		mo->set(i, col1, mo->at(i, col2));
		mo->set(i, col2, temp);
	}
	return *mo;
}

void colPermuate(const Matrix& ms, const Matrix& me, int step, vector<int> order)
{
	int ecol = order.size();
#ifdef DEBUGC
	cout << "ms : " << endl <<  ms;
	cout << "me : " << endl << me;
	cout << "step : " << step << " ecol : " << ecol << endl;
#endif
	if (order.size() == me.col) {
		if (step + rstep < ans)
			ans = step + rstep;
		return;
	}

	for (int scol = ecol; scol < me.col; scol++) {
		if (compareColumn(ms, me, scol, ecol) == 0)  {
			vector<int> noworder(order);
#ifdef DEBUGC
			cout << "col: " <<  ecol << " " << scol <<  endl;
#endif
			noworder.push_back(scol);
			if (ecol == scol) 
				colPermuate(ms, me, step, noworder); 
			else  {
				Matrix m = colChange(ms, ecol, scol);
				colPermuate(m, me, step + 1, noworder); 
			}
		}
	}
}

Matrix&  rowChange(const Matrix& m, vector<int> order) {
	Matrix* mo = new Matrix(m);
	for (vector<int>::iterator iter = order.begin(); iter != order.end(); iter++) {
		for (int i = 0; i < m.col; i++) 
			mo->set(*iter, i, 1 - mo->at(*iter, i)); 
	}
	return *mo;
}

//Matrix rowChange(const Matrix& m, vector<int> order) {
//	Matrix mo(m);
//	for (vector<int>::iterator iter = order.begin(); iter != order.end(); iter++) {
//		for (int i = 0; i < m.col; i++) 
//			mo.set(*iter, i, 1 - mo.at(*iter, i)); 
//	}
//	return mo;
//}
//
void rowPermuate(const Matrix& ms, const Matrix& me, int len, vector<int> order) {
#ifdef DEBUG
	cout << "rowPermuate : " << len << " " << order.size() << endl;
	cout << "+++ order : " << order << endl;
#endif
	if (order.size() > len) return;

	for (int i = 0; i < ms.row; i++) {
		if (order.size() == 0 || i > order[order.size() - 1]) {
			vector<int> noworder(order);
			noworder.push_back(i);
#ifdef DEBUG
			cout << "++order : " << order << endl;
			cout << "++noworder: " << noworder << endl;
#endif
			if (noworder.size() == len) {
				Matrix m = rowChange(ms, noworder);
				vector<int> order2;
				rstep = len;
#ifdef DEBUG
				cout << noworder << endl << m;
#endif
				colPermuate(m, me, 0, order2);
			} else 
				rowPermuate(ms, me, len, noworder);
		}
	}
}

int main()
{
	int cnt;
	cin >> cnt;
	while (cnt--) {
		int col, row;
		cin >> row >> col;
		Matrix ms(row, col), me(row, col);
		cin >> ms >> me;
		ans = MAX;

		if (ms == me) {
			cout << 0 << endl;
		} else {
			vector<int> order;
#ifdef DEBUG
			cout << ms ;
			cout << me ;
#endif
			colPermuate(ms, me, 0, order);

			if (ans != MAX) {
				cout << ans << endl;
			} else {
				for (int i = 1; i <= row; i++) {
					vector<int> order;
					rowPermuate(ms, me, i, order);
					if (ans != MAX) {
						break;
					}
				}
				if (ans == MAX)
					cout << -1 << endl;
				else
					cout << ans << endl;
			}
		}
	}
	
}
